package network

import (
	"bytes"
	"distcompiler/common"
	"embed"
	"encoding/binary"
	"io/fs"
	"log"
	"net/http"
	"strings"

	"github.com/gin-gonic/gin"
	"github.com/gorilla/websocket"
)

//go:embed dist/*
var embedFs embed.FS
var ws *websocket.Conn

type pack_data struct {
	from_ip [16]byte
	to_ip   [16]byte
	time    [16]byte
	len     uint32
	dtype   byte
	data    []byte
}

func Byte2Pack(data []byte) pack_data {
	var value pack_data
	binary.Read(bytes.NewBuffer(data), binary.BigEndian, value)
	return value
}
func Pack2Byte(data pack_data) []byte {
	bytesBuffer := bytes.NewBuffer([]byte{})
	binary.Write(bytesBuffer, binary.BigEndian, data)
	return bytesBuffer.Bytes()
}

func ReceiveChatData(data pack_data) {
	common.Put(append(append(append(data.from_ip[:], data.to_ip[:]...), 0x20), data.time[:]...), Pack2Byte(data))
	err := ws.WriteMessage(websocket.BinaryMessage, Pack2Byte(data))
	if err != nil {
		log.Println("receive:", err)
	}
}
func SendChatData(data pack_data) {
	if strings.Trim(string(data.to_ip[:]), "\x00") != "" {
		common.Put(append(append(append(data.from_ip[:], data.to_ip[:]...), 0x20), data.time[:]...), Pack2Byte(data))
		err := SendData(strings.Trim(string(data.to_ip[:]), "\x00"), Pack2Byte(data))
		if err != nil {
			log.Println("send:", err)
		}
	}
}
func HttpRun() {
	e := gin.Default()
	fdist, _ := fs.Sub(embedFs, "dist")
	fjs, _ := fs.Sub(fdist, "js")
	fcss, _ := fs.Sub(fdist, "css")
	e.StaticFS("/js", http.FS(fjs))
	e.StaticFS("/css", http.FS(fcss))
	e.GET("/", func(c *gin.Context) {
		c.FileFromFS("/", http.FS(fdist))
	})
	e.GET("/chat/computer", func(c *gin.Context) {
		c.JSON(http.StatusOK, GetServers())
	})
	e.POST("/chat/receive", func(ctx *gin.Context) {

	})
	e.POST("/chat/send", func(ctx *gin.Context) {

	})
	e.POST("/chat/get_chat", func(c *gin.Context) {
		target := c.Query("target")
		data := common.Get([]byte(target))
		c.Data(http.StatusOK, "application/json", data)
	})
	e.POST("/chat/get_chat_history", func(c *gin.Context) {
		target := c.Query("target")
		data := common.Get([]byte(target))
		c.Data(http.StatusOK, "application/json", data)
	})
	e.GET("/ws", func(c *gin.Context) {
		var upGrader = websocket.Upgrader{
			CheckOrigin: func(r *http.Request) bool {
				return true
			},
		}
		var err error
		ws, err = upGrader.Upgrade(c.Writer, c.Request, nil)
		if err != nil {
			log.Print(err)
			return
		}
		defer ws.Close()
		for {
			_, message, err := ws.ReadMessage()
			if err != nil {
				log.Println(err)
				break
			}
			SendChatData(Byte2Pack(message))
		}
	})
	e.GET("/app/list", func(c *gin.Context) {
		c.Query("all")
		c.Data(http.StatusOK, "application/json", make([]byte, 0))
	})
	e.Run(":9001")
}
